<?php
namespace app\common\lib\user_operate;

use app\common\lib\Common;
use app\common\lib\EntranceToken as ET;

class ModuleOperate
{
    private $common; //操作实例

    public $storeId; //模块id

    public $pluginName; //模块名称

    public function __construct()
    {
        $this->common = new Common;

    }

    /**
     * 安装模块
     */
    public function install()
    {
        $data = [
            'token' => ET::getToken(),
            'param' => [
                'type'     => '2020043008',
                'store_id' => $this->storeId,
            ],
        ];

        $res = $this->common->requestInterface(ET::getUrl(), $data);

        if (isset($res['data']['code']) && !empty($res['data']['code'])) {

            $res = $this->addInstallIni($res['data']['code']);
        }

        return $res;
    }

    /**
     * 添加 code 到 install.ini文件
     * @param [type] $code [description]
     */
    public function addInstallIni($code)
    {
        $pluginName = $this->pluginName;

        $pluginName = cmf_parse_name($pluginName);

        $data['code'] = $code;
        if (saveModuleConfigData($pluginName, 'config', 'install.ini', $data)) {
            $mesg = (APP_DEBUG) ? '安装失败,请检查是否又写入权限' : '安装失败,请稍后再试';
            return ['status' => 'error', 'message' => $mesg, 'code' => 103];
        }
        return true;
    }

    /**
     * 更新模块
     */
    public function update($pluginName = '', $store_id = '', $code = '')
    {
        if (empty($pluginName) || empty($code) || empty($store_id)) {
            return ['status' => 'error', 'message' => '参数错误！', 'code' => 101];
        }

        $pluginName = cmf_parse_name($pluginName);
        $menu       = getModuleConfig($pluginName, 'config', 'menu.php');
        //检测菜单配置文件
        $check = $this->checkMenu($pluginName, $store_id, $menu);

        if ($check['status'] != 'success') {
            return $check;
        }

        $data = [
            'token' => ET::getToken(),
            'param' => [
                'type' => '2020050411',
                'code' => $code,
                'menu' => $menu,
            ],
        ];
        $res = $this->common->requestInterface(ET::getUrl(), $data);

        return $res;
    }

    /**
     * 检查菜单配置是否异常
     */
    protected function checkMenu($pluginName, $store_id, $menu)
    {
        $pluginName = cmf_parse_name($pluginName, 1);

        //判断文件格式是否正确
        if (!is_array($menu) || empty($menu)) {
            return ['status' => 'error', 'message' => '菜单配置错误！', 'code' => 102];
        }

        $key     = array_keys($menu)[0];
        $key_arr = explode('@', $key);
        //验证模块名
        if (empty($key_arr) || $pluginName != cmf_parse_name($key_arr[0], 1)) {
            return ['status' => 'error', 'message' => '菜单模块名配置错误！', 'code' => 103];
        }

        //获取模块详情
        $mk_arr = $this->getModuleList($store_id);
        if (empty($mk_arr)) {
            return ['status' => 'error', 'message' => '模块列表中不存在此模块！', 'code' => 104];
        }

        //验证版本
        if ($mk_arr['version'] != $key_arr[1]) {
            return ['status' => 'error', 'message' => '菜单配置版本号错误！', 'code' => 105];
        }

        foreach ($menu[$key] as $k => $v) {

            if (empty($v['controller']) || empty($v['action'])) {
                return ['status' => 'error', 'message' => '菜单配置控制器或方法未定义！', 'code' => 107];
            }

            //验证是否是主菜单
            $contro = ['AdminIndex', 'admin_index', 'Admin_Index'];
            $act    = ['index', 'Index'];
            if (in_array($v['controller'], $contro) && in_array($v['action'], $act)) {
                return ['status' => 'error', 'message' => '不能设置AdminIndex控制器的index方法为子菜单！', 'code' => 108];
            }

            //验证控制器和方法是否定义
            $class = 'plugins' . '\\' . cmf_parse_name($pluginName) . '\\' . 'controller' . '\\' . $v['controller'] . 'Controller';

            if (!class_exists($class) || !method_exists($class, $v['action'])) {

                return ['status' => 'error', 'message' => '未定义类' . $v['controller'] . '或方法' . $v['action'], 'code' => 106];
            }
        }

        return ['status' => 'success', 'message' => '验证通过', 'code' => 200];
    }

    /**
     * 卸载模块
     */
    public function uninstall()
    {
        $data = [
            'token' => ET::getToken(),
            'param' => [
                'type'     => '2020043009',
                'store_id' => $this->storeId,
            ],
        ];
        $res = $this->common->requestInterface(ET::getUrl(), $data);

        return $res;
    }

    /**
     * 获取模块列表
     * $store_id 模块id 传值查看详情
     * @return [type] [description]
     */
    public function getModuleList($store_id = '')
    {
        $data = [
            'token' => ET::getToken(),
            'param' => [
                'type' => '2020052806',
            ],
        ];
        $res = $this->common->requestInterface(ET::getUrl(), $data);

        if ($res['status'] == 'success' && !empty($store_id)) {

            $ids = array_column($res['data'], 'store_id');
            //获取模块详情
            $key = array_search($store_id, $ids);

            if ($key === false) {
                return [];
            }
            $value = $res['data'][$key];

            return $value;
        }

        return $res;
    }

    /**
     * 模块是否安装
     */
    public function installStatus($moduleName = '', $code = '')
    {
        if (empty($moduleName) || empty($code)) {
            return ['status' => false, 'message' => '参数错误！', 'code' => 101];
        }

        // dump($moduleName);
        // dump($code);

        $moduleName = cmf_parse_name($moduleName, 1);

        //检测模块是否存在
        $status = $this->checkModuleFileIsExist($moduleName);
        if ($status == false) {
            return ['status' => false, 'message' => '模块不存在', 'code' => 102];
        }

        //检测ini文件
        $pipei = $this->checkIni($moduleName, $code);

        // dump($pipei);exit;
        if ($pipei) {
            return ['status' => true, 'message' => '已安装', 'code' => 200];
        } else {
            return ['status' => false, 'message' => '未安装！请清除缓存后重试', 'code' => 103];
        }
    }

    /**
     * 检测install.ini 文件是否匹配
     */
    public function checkIni($moduleName, $code)
    {
        $ini = getModuleConfig($moduleName, 'config', 'install.ini');
        $ini = json_decode($ini, true);

        // dump($code);
        // dump($ini);

        if ($code != $ini['code']) {
            return false;
        }
        return true;
    }

    /**
     * 检测模块文件是否存在
     */
    public function checkModuleFileIsExist($symbol, $file = '')
    {
        //检测模块类是否定义
        $class = cmf_get_plugin_class($symbol);
        if (!class_exists($class)) {
            return false;
        }

        //检测控制器主类和index方法 是否定义\
        $admin_class = 'plugins\\' . cmf_parse_name($symbol) . '\\controller\\AdminIndexController';
        if (!class_exists($admin_class) || !method_exists($admin_class, 'index')) {
            return false;
        }

        return true;
    }

    /**
     * 获取模块下载地址
     * @return [type] [description]
     */
    public function getSourceAddr()
    {
        if (empty($this->storeId)) {
            return ['status' => 'error', 'message' => '模块id不能为空', 'code' => '101'];
        }

        $data = [
            'token' => ET::getToken(),
            'param' => [
                'type'     => '2020042907',
                'store_id' => $this->storeId,
            ],
        ];
        $res = $this->common->requestInterface(ET::getUrl(), $data);

        if (isset($res['data']) && !empty($res['data'])) {
            $res['data'] = urldecode($res['data']);
        }

        return $res;
    }

}
